﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TimeSheetNote
{
    public partial class FormAllTasks : Form
    {
        public const bool bDeleteVisible = false;

        List<TaskEl> tskL = null;

        DateTime dtNextSave = DateTime.Now.AddSeconds(10);

        public FormAllTasks()
        {
            InitializeComponent();
        }

        public void ShowDialog1()
        {
            tskL = new List<TaskEl>(Gl.TL);
            TaskEl.CmprMode = TaskEl.CompareMode.LastDate;
            tskL.Sort();
            RefillTasks(false);
            ShowDialog();
        }

        private void FormAllTasks_Shown(object sender, EventArgs e)
        {
            lvTasks.Focus();
        }

        /*void AddTaskControl(TaskEl tsk)
        {
            TaskAllCntrl tskCntrl = new TaskAllCntrl(pnlTasks, tl.Count, tsk);
            tskCntrl.UserModifyText += new EventHandler(Task_UserModifyText);
            tskCntrl.UserModifyTime += new EventHandler(Task_UserModifyTime);
            tskCntrl.DeleteClick += new EventHandler(Task_Delete);
            tskCntrl.DeleteDayBeforeClick += new EventHandler(Task_DayDeleteBefore);
            tskCntrl.DeleteDayClick += new EventHandler(Task_DayDelete);
            tskCntrl.CloseClick += new EventHandler(Task_OpenClose);
            tl.Add(tskCntrl);
        }*/

        #region *** события Task ************************************************************************

        /*bool bModifyText = false;
        void Task_UserModifyText(object sender, EventArgs e)
        {
            dtNextSave = DateTime.Now.AddSeconds(2);
            bModifyText = true;
        }

        void Task_UserModifyTime(object sender, EventArgs e)
        {
            dtNextSave = DateTime.Now.AddSeconds(2);
        }

        void Task_Delete(object sender, EventArgs e)
        {
            if (MessageBox.Show("Действительно удалить задачу?", "Удаление задачи", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return;

            int val = pnlTasks.VerticalScroll.Value;
            pnlTasks.VerticalScroll.Value = 0;

            DeleteTask((TaskAllCntrl)sender);

            ReposTasks();

            pnlTasks.VerticalScroll.Value = val > pnlTasks.VerticalScroll.Maximum ? pnlTasks.VerticalScroll.Maximum : val;
            pnlTasks.VerticalScroll.Value = val > pnlTasks.VerticalScroll.Maximum ? pnlTasks.VerticalScroll.Maximum : val;

            dtNextSave = DateTime.Now;
        }

        void DeleteTask(TaskAllCntrl tskCntrl)
        {

            TaskEl tsk = ((TaskAllCntrl)tskCntrl).Tsk;
            int ind = ((TaskAllCntrl)tskCntrl).Ind;

            if (tsk.ID < 0) return;

            Gl.TL.Remove(tsk);

            tl[ind].Dispose();
            tl.RemoveAt(ind);
        }

        int tmpValScroll;
        void Task_DayDeleteBefore(object sender, EventArgs e)
        {
            tmpValScroll = pnlTasks.VerticalScroll.Value;
            pnlTasks.VerticalScroll.Value = 0;
        }

        void Task_DayDelete(object sender, EventArgs e)
        {
            if (((TaskAllCntrl)sender).Tsk.Days.Count == 0)
            {
                DeleteTask((TaskAllCntrl)sender);
            }
            ReposTasks();
            dtNextSave = DateTime.Now;

            pnlTasks.VerticalScroll.Value = tmpValScroll > pnlTasks.VerticalScroll.Maximum ? pnlTasks.VerticalScroll.Maximum : tmpValScroll;
            pnlTasks.VerticalScroll.Value = tmpValScroll > pnlTasks.VerticalScroll.Maximum ? pnlTasks.VerticalScroll.Maximum : tmpValScroll;

            dtNextSave = DateTime.Now;

            RefillTasks();
        }

        void Task_OpenClose(object sender, EventArgs e)
        {
            dtNextSave = DateTime.Now;
        }
        */
        #endregion *** события Task ************************************************************************

        private void tmr_Tick(object sender, EventArgs e)
        {
            tmr.Stop();

            // сохранение
            if (dtNextSave <= DateTime.Now)
            {
                dtNextSave = DateTime.Now.AddSeconds(10);
                Gl.SaveDB();
            }

            tmr.Start();
        }

        private void Flt_Changed(object sender, EventArgs e)
        {
            RefillTasks(true);
        }

        private void chbxFltDay_CheckedChanged(object sender, EventArgs e)
        {
            cldFltDay.Enabled = chbxFltDay.Checked;
            RefillTasks(true);
        }

        void RefillTasks(bool SaveSelection)
        {
            int selectedTaskID = int.MinValue;
            if (lvTasks.SelectedItems.Count > 0) selectedTaskID = (lvTasks.SelectedItems[0].Tag as TaskEl).ID;
            lvTasks.Items.Clear();
            RefillTaskData(null);
            int selectedTaskInd = -1;
            for (int i = tskL.Count - 1; i >= 0; i--)
            {
                bool inFilter = true;
                if (txbFltID.Text.Trim() != "")
                {
                    int fltID;
                    if (!int.TryParse(txbFltID.Text.Trim(), out fltID)) txbFltID.Text = "";
                    else if (fltID != tskL[i].ID) inFilter = false;
                }

                if (inFilter && chbxFltDay.Checked)
                {
                    bool bExistDay = false;
                    foreach (KeyValuePair<DateTime, int> day in tskL[i].Days) if (day.Key == cldFltDay.Value.Date) { bExistDay = true; break; }
                    if (!bExistDay) inFilter = false;
                }

                if (inFilter && txbFltText.Text.Trim() != "")
                {
                    if (!tskL[i].Text.ToUpper().Contains(txbFltText.Text.Trim().ToUpper())) inFilter = false;
                }

                if (inFilter)
                {
                    if (tskL[i].ID == selectedTaskID) selectedTaskInd = lvTasks.Items.Count;
                    ListViewItem itm = new ListViewItem(tskL[i].ID.ToString());
                    itm.Tag = tskL[i];
                    for (int n = 1; n < lvTasks.Columns.Count; n++) itm.SubItems.Add("");
                    RefillTaskLine(itm);
                    lvTasks.Items.Add(itm);
                }
            }

            if (SaveSelection && selectedTaskID != int.MinValue && selectedTaskInd != -1)
            {
                lvTasks.SelectedIndices.Add(selectedTaskInd);
                lvTasks.SelectedItems[0].EnsureVisible();
            }
        }

        void RefillTaskLine(ListViewItem Itm)
        {
            TaskEl tsk = (TaskEl)Itm.Tag;
            Itm.SubItems[1].Text = tsk.Text;
            Itm.SubItems[2].Text = Math.Round(tsk.TotalTime / 3600.0, 3).ToString();
            Itm.SubItems[3].Text = tsk.GetLastDay().ToString("dd.MM.yyyy");
            Itm.SubItems[4].Text = tsk.IsClose ? "V" : "";
        }

        bool bRefillTaskData = false;
        void RefillTaskData(TaskEl tsk)
        {
            bRefillTaskData = true;
            txbText.Text = "";
            btnClose.Visible = false;
            foreach (TaskDayCntrl cntrl in dl) cntrl.Dispose();
            dl.Clear();

            if (tsk != null)
            {
                txbText.Text = tsk.Text;
                btnClose.Visible = true;
                btnClose.Image = tsk.IsClose ? Properties.Resources.Close : Properties.Resources.Open;
                // формирование списка дней
                foreach (KeyValuePair<DateTime, int> day in tsk.Days)
                    AddDayControl(day.Key, day.Value);
                for (int i = 0; i < dl.Count; i++)
                    dl[i].Ind = i;
            }
            bRefillTaskData = false;
        }

        private void lvTasks_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lvTasks.SelectedIndices.Count == 0) return;
            RefillTaskData((TaskEl)lvTasks.SelectedItems[0].Tag);
        }

        void Day_UserModifyTime(object sender, EventArgs e)
        {
            TaskEl tsk = (TaskEl)lvTasks.SelectedItems[0].Tag;
            tsk.Days[((TaskDayCntrl)sender).ActDay] = ((TaskDayCntrl)sender).Time;
            dtNextSave = DateTime.Now.AddSeconds(2);
            RefillTaskLine(lvTasks.SelectedItems[0]);
        }

        /*void Day_Delete(object sender, EventArgs e)
        {
            int ind = ((TaskDayCntrl)sender).Ind;
            if (MessageBox.Show("Действительно удалить день?", "Удаление дня", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return;
            TaskEl tsk = (TaskEl)lvTasks.SelectedItems[0].Tag;
            tsk.Days.Remove(dl[ind].ActDay);
            dl[ind].Dispose();
            dl.RemoveAt(ind);
            ReposDays();
            dtNextSave = DateTime.Now;
        }*/

        List<TaskDayCntrl> dl = new List<TaskDayCntrl>();

        void AddDayControl(DateTime day, int time)
        {
            TaskDayCntrl dayCntrl = new TaskDayCntrl(pnlDays, dl.Count, day, time);
            dayCntrl.UserModifyTime += new EventHandler(Day_UserModifyTime);
            //dayCntrl.DeleteClick += new EventHandler(Day_Delete);
            dl.Add(dayCntrl);
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            TaskEl tsk = (TaskEl)lvTasks.SelectedItems[0].Tag;
            tsk.IsClose = !tsk.IsClose;
            RefillTaskLine(lvTasks.SelectedItems[0]);
            dtNextSave = DateTime.Now;
        }

        private void txbText_TextChanged(object sender, EventArgs e)
        {
            if (bRefillTaskData) return;
            TaskEl tsk = (TaskEl)lvTasks.SelectedItems[0].Tag;
            tsk.Text = txbText.Text;
            dtNextSave = DateTime.Now.AddSeconds(2);
            RefillTaskLine(lvTasks.SelectedItems[0]);
        }

    }

    class TaskDayCntrl
    {
        Control ParentControl;
        Label lblDay = new Label();
        NumericUpDown numericUpDown1 = new NumericUpDown();
        NumericUpDown numericUpDown2 = new NumericUpDown();
        Panel panel1 = new Panel();
        //Button btnDel = new Button();

        bool bSet = false;

        public DateTime ActDay;

        #region *** свойства ***********************************************************

        public int Time { get { return (int)numericUpDown1.Value * 3600 + (int)numericUpDown2.Value * 60; } }

        int ind;
        public int Ind { get { return ind; } set { ind = value; panel1.Top = GetPosY(ind); } }

        #endregion *** свойства ***********************************************************

        #region *** события ******************************************

        public event EventHandler UserModifyTime;
        void OnUserModifyTime() { if (UserModifyTime != null) UserModifyTime(this, new EventArgs()); }

        /* public event EventHandler DeleteClick;
         void OnDeleteClick() { if (DeleteClick != null) DeleteClick(this, new EventArgs()); }*/

        #endregion *** события ******************************************

        #region *** конструкторы ***********************************************************

        public TaskDayCntrl(Control ParentControl, int Ind, DateTime ActDay, int Time)
        {
            this.ParentControl = ParentControl;

            this.ind = Ind;

            AddControls();

            this.ActDay = ActDay;
            lblDay.Text = ActDay.ToString("dd.MM.yyyy");

            bSet = true;
            numericUpDown1.Value = Time / 3600;
            numericUpDown2.Value = (Time - (Time / 3600) * 3600) / 60;
            bSet = false;

        }

        void AddControls()
        {
            ParentControl.SuspendLayout();
            lblDay.Location = new Point(5, 4);
            lblDay.TabStop = false;

            numericUpDown1.Location = new Point(90, 1);
            numericUpDown1.Size = new Size(38, 20);
            numericUpDown1.Value = 0;
            numericUpDown1.ValueChanged += new EventHandler(num_TextChanged);
            numericUpDown1.TabStop = false;

            numericUpDown2.Location = new Point(130, 1);
            numericUpDown2.Size = new Size(38, 20);
            numericUpDown2.Value = 0;
            numericUpDown2.ValueChanged += new EventHandler(num_TextChanged);
            numericUpDown2.Maximum = 59;
            numericUpDown2.TabStop = false;

            /*btnDel.Location = new Point(175, -3);
            btnDel.Size = new Size(16, 16);
            btnDel.Image = Properties.Resources.delete;
            btnDel.Click += new EventHandler(BtnDel_Click);*/

            //panel1.Controls.Add(btnDel);
            panel1.Controls.Add(numericUpDown2);
            panel1.Controls.Add(numericUpDown1);
            panel1.Controls.Add(lblDay);
            panel1.Location = new Point(0, GetPosY(ind));
            panel1.Size = new Size(175, 25);
            panel1.BorderStyle = BorderStyle.FixedSingle;

            //panel1.Anchor = AnchorStyles.Top | AnchorStyles.Right;

            ParentControl.ResumeLayout();
            ParentControl.Controls.Add(panel1);
        }

        #endregion *** конструкторы ***********************************************************

        int GetPosY(int ind)
        {
            return 25 * ind;
        }

        private void num_TextChanged(object sender, EventArgs e)
        {
            if (bSet) return;
            OnUserModifyTime();
        }

        /*private void BtnDel_Click(object sender, EventArgs e)
        {
            OnDeleteClick();
        }*/

        public void Dispose()
        {
            ParentControl.Controls.Remove(panel1);
            panel1.Dispose();
        }
    }

}
